/**
 * Copyright (c) 2012, Hakans Pirates - 
 * Johan Andersson spaiki17@gmail.com, 
 * Mattias Lundberg lundberg.mattias@gmail.com, 
 * Samuel Sjodin sjoodin@gmail.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *  
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package pirates;

import java.util.Iterator;
import java.util.Random;

import com.jme3.math.Matrix3f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import pirates.notifications.Notify;

/**
 * 
 * various useful classes
 * 
 * @author samsjo-8
 * 
 */
public class Utils {

	public static final Matrix3f rotate90X = new Matrix3f(1f, 0f, 0f, 0f, 0f,
			1f, 0f, -1f, 0f);
	public static final Matrix3f rotate90Y = new Matrix3f(0f, 0f, -1f, 0f, 1f,
			0f, 1f, 0f, 0f);
	public static final Matrix3f rotate90Z = new Matrix3f(0f, 1f, 0f, -1f, 0f,
			0f, 0f, 0f, 1f);

	/**
	 * 
	 * @param pos
	 *            - position to spawn near
	 * @param maxRadius
	 *            - spawnRadiusFromPoint
	 * @param ships
	 *            - the Node with ships (a number of spatials)
	 * @return a position near the given pos that is free to spawn at and within
	 *         MaxRadius.
	 */
	public static Vector3f getUntakenSpawnPoint(Vector3f pos, float maxRadius,
			Node ships) {
		return getRandomFreeLocation(pos, maxRadius, ships);

	}

	private static Vector3f getRandomFreeLocation(Vector3f pos,
			float spawnRadius, Node nodeWithSpatials) {
		Vector3f loc;
		Iterator<Spatial> i = nodeWithSpatials.getChildren().iterator();
		loc = getRandomMapLocation(pos, spawnRadius);
		Spatial a;
		while (i.hasNext()) { // check all ships, see if any one is too close -
								// if true, try new random value)
			a = i.next();
			if (loc.distance(a.getWorldTranslation()) <= Settings.SPAWN_AREA_RADIUS) {
				Notify.debug("recursive call");
				try {
					return getRandomFreeLocation(pos, spawnRadius,
							nodeWithSpatials);
				} catch (StackOverflowError e) {
					// just return the location, we don't want the program to
					// crash
					Notify.debug("warning - difficult to find enough room!");
					break;
				}

			}
		}
		return loc;
	}

	/**
	 * 
	 * @param pos
	 * @param spawnRadius
	 *            - spawn radius from point
	 * @return
	 */
	private static Vector3f getRandomMapLocation(Vector3f pos, float spawnRadius) {
		// int fromX = -500;
		// int fromY =
		Random r = new Random(System.nanoTime());
		float x = (r.nextFloat() - 0.5f) * spawnRadius;// Settings.
		float y = 0;
		float z = (r.nextFloat() - 0.5f) * spawnRadius;
		return pos.add(new Vector3f(x, y, z));

	}

	public static boolean close(Vector3f pos, Vector3f pos2, int distance) {
		if (pos.x < pos2.x + distance && pos.x > pos2.x - distance
				|| pos.y < pos2.y + distance && pos.y > pos2.y - distance
				|| pos.z < pos2.z + distance && pos.z > pos2.z - distance) {
			return true;
		}
		return false;
	}
}
